Skip to content

Fix SymbolMappingMsg hd.length on cross-version encode#21

Merged
tbeason merged 3 commits into
mainfrom
fix/symbol-mapping-version-rewrite
May 25, 2026
Merged

Fix SymbolMappingMsg hd.length on cross-version encode#21
tbeason merged 3 commits into
mainfrom
fix/symbol-mapping-version-rewrite

Conversation

@tbeason

@tbeason tbeason commented May 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Encoder now rewrites SymbolMappingMsg.hd.length to match the layout it actually serializes (20 for v1, 44 for v2+), instead of passing the input record's hd.length through unchanged.
  • Fixes a silent file-corruption bug surfaced by DatabentoAPI.jl's live capture: the Databento Live gateway emits SymbolMappingMsg in v1 wire layout (hd.length=20, 80 bytes) even when the consumer is writing a v3 file. The encoder picked the v2+ body (160 bytes) but wrote the original hd.length=20 header — the decoder then mis-aligned and every record after the mapping was unreadable.
  • Adds a regression test (SymbolMappingMsg cross-version (v1 wire → v3 file)) that writes a v1-wire mapping followed by a TradeMsg into a v3 file and verifies both round-trip with the mapping's hd.length rewritten to 44 on disk.

Context

Downstream report and workaround: tbeason/DatabentoAPI.jl#14 (JSONL sidecar). Once this fix is released, the workaround can be removed there.

Test plan

  • include("test/runtests.jl") — Phase 8 testset is now 102 passing (was 94). Other 3408 tests unchanged.
  • DatabentoAPI.jl test suite (pkg> test DatabentoAPI) — all 241 pass against this branch via the local-path dep.
  • Manual end-to-end: v1-wire SymbolMappingMsg (hd.length=20) + trailing TradeMsg written to a v3 file, both decode cleanly; mapping's on-disk hd.length is 44.

🤖 Generated with Claude Code

tbeason and others added 3 commits May 25, 2026 10:34
The Databento Live gateway emits SymbolMappingMsg in v1 wire layout
(hd.length=20, 80 bytes total) even when the consumer is writing into a
v3 file. The encoder dispatched on metadata.version to pick the body
layout (v1: 64-byte body; v2+: 160-byte body) but wrote the record's
original hd.length unchanged. The on-disk header then disagreed with the
body that followed it, mis-aligning the decoder and corrupting every
subsequent record in the stream.

Re-derive hd.length from the layout actually being serialized
(20 for v1, 44 for v2+) before writing the record header. The struct
itself carries only parsed values, so the input version doesn't matter;
the output is always self-consistent with the file's metadata.version.

Added a regression test that constructs a v1-wire SymbolMappingMsg
(hd.length=20), writes it into a v3 file alongside a trailing TradeMsg,
and verifies both records round-trip cleanly with the symbology record's
length rewritten to 44 on disk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-1.0 minor bump for the SymbolMappingMsg encoder fix: behavior of
the encoder on cross-version writes changed (records that previously
produced corrupt files now produce correct ones, and the on-disk
hd.length of SymbolMappingMsg records is normalized to the file's
metadata.version). Downstream consumers should opt in via their
[compat] entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous commit bumped to 0.2.0; the encoder fix is a bug fix without
breaking API change, so patch is the right level. Downstream [compat]
"0.1" entries pick it up automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tbeason
tbeason merged commit 7c8b80d into main May 25, 2026
8 checks passed
@tbeason
tbeason deleted the fix/symbol-mapping-version-rewrite branch May 25, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant